home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / mint / mntlb20 / lib / _normsf.cpp < prev    next >
Text File  |  1992-03-30  |  3KB  |  148 lines

  1. | mjr: _normsf is not needed if the 68881 is present
  2. | but _infinitysf is retained
  3.  
  4. |#######################################################################
  5.  
  6. | single floating point normalization routine
  7. |
  8. | written by Kai-Uwe Bloem (I5110401@dbstu1.bitnet).
  9. | Based on a 80x86 floating point packet from comp.os.minix, written by P.Housel
  10. |
  11. |
  12. | Revision 1.4, kub 03-90 :
  13. | export ___normsf entry to C language. Rename the internal entry to a name
  14. | not accessible from C to prevent crashes
  15. |
  16. | Revision 1.3, kub 01-90 :
  17. | added support for denormalized numbers
  18. |
  19. | Revision 1.2, kub 01-90 :
  20. | replace far shifts by swaps to gain speed
  21. |
  22. | Revision 1.1, kub 12-89 :
  23. | Ported over to 68k assembler
  24. |
  25. | Revision 1.0:
  26. | original 8088 code from P.S.Housel
  27.  
  28.     .text
  29.     .even
  30.     .globl    __infinitysf
  31. #if !defined (__M68881__) && !defined (sfp004)
  32.     .globl    ___normsf
  33.     .globl    norm_sf
  34.  
  35. #ifdef    ERROR_CHECK
  36. LC0:
  37.     .ascii "normsf: OVERFLOW\12\15\0"
  38.     .even
  39. #endif    ERROR_CHECK
  40.  
  41.     | C entry, for procs dealing with the internal representation :
  42.     | float __normsf(long mant, short exp, short sign, short rbits);
  43. ___normsf:
  44.     lea    sp@(4),a0    | parameter pointer
  45.     moveml    d2-d5,sp@-    | save working registers
  46.     movel    a0@+,d4        | get mantissa
  47.     movew    a0@+,d0        | get exponent
  48.     movew    a0@+,d2        | get sign
  49.     movew    a0@+,d1        | rounding information
  50.  
  51.     | internal entry for floating point package, saves time
  52.     | d0=u.exp, d2=u.sign, d1=rounding bits, d4/d5=mantissa
  53.     | registers d2-d7 must be saved on the stack !
  54. norm_sf:
  55.     tstl    d4        | rounding and u.mant == 0 ?
  56.     bne    0f
  57.     tstb    d1
  58.     beq    retz
  59. 0:
  60.     clrb    d2        | "sticky byte"
  61.     movel    #0xff000000,d5
  62. 1:    tstw    d0        | divide (shift)
  63.     ble    0f        |  denormalized number
  64.     movel    d4,d3
  65.     andl    d5,d3        |  or until no bits above 23
  66.     beq    2f
  67. 0:    addw    #1,d0        | increment exponent
  68.     lsrl    #1,d4
  69.     orb    d1,d2        | set "sticky"
  70.     roxrb    #1,d1        | shift into rounding bits
  71.     bra    1b
  72. 2:
  73.     andb    #1,d2
  74.     orb    d2,d1        | make least sig bit "sticky"
  75.     movel    #0xff800000,d5
  76. 3:    movel    d4,d3        | multiply (shift) until
  77.     andl    d5,d3        | one in "implied" position
  78.     bne    4f
  79.     subw    #1,d0        | decrement exponent
  80.     beq    4f        |  too small. store as denormalized number
  81.     addb    d1,d1        | some doubt about this one *
  82.     addxl    d4,d4
  83.     bra    3b
  84. 4:
  85.     tstb    d1        | check rounding bits
  86.     bge    6f        | round down - no action neccessary
  87.     negb    d1
  88.     bvc    5f        | round up
  89.     bclr    #0,d4        | tie case - round to even
  90.     bra    6f
  91. 5:
  92.     clrw    d1        | zero rounding bits
  93.     addl    #1,d4
  94.     tstw    d0
  95.     bne    0f        | renormalize if number was denormalized
  96.     addw    #1,d0        | correct exponent for denormalized numbers
  97.     bra    1b
  98. 0:    movel    d4,d3        | check for rounding overflow
  99.     andl    #0xff000000,d3
  100.     bne    1b        | go back and renormalize
  101. 6:
  102.     tstl    d4        | check if normalization caused an underflow
  103.     beq    retz
  104.     cmpw    #0,d0        | check for exponent overflow or underflow
  105.     blt    retz
  106.     cmpw    #255,d0
  107.     bge    oflow
  108.  
  109.     lslw    #7,d0        | re-position exponent
  110.     andw    #0x8000,d2    | sign bit
  111.     orw    d2,d0
  112.     swap    d0        | map to upper word
  113.     clrw    d0
  114.     andl    #0x7fffff,d4    | top mantissa bits
  115.     orl    d4,d0        | insert exponent and sign
  116.     moveml    sp@+,d2-d5
  117.     rts
  118.  
  119. retz:    clrl    d0
  120.     moveml    sp@+,d2-d5
  121.     rts
  122.  
  123. oflow:    
  124.  
  125. #ifdef    ERROR_CHECK
  126.     moveml    d0-d1,a7@-
  127.     pea    LC0
  128.     pea    __iob+52    |
  129.     jbsr    _fprintf    |
  130.     addql    #8,a7        |
  131.     moveml    a7@+,d0-d1
  132. #endif    ERROR_CHECK
  133.  
  134.     movel    __infinitysf,d0    | return infinty value
  135.  
  136.     btst    #15,d2        | transfer sign
  137.     beq    ofl_clear    | (mjr++)
  138.     bset    #31,d0        |
  139.     rts
  140. ofl_clear:
  141.     moveml    sp@+,d2-d5    | should really cause trap ?!?
  142.     rts
  143.  
  144. #endif __M68881__
  145.  
  146. __infinitysf:            | +infinity as proposed by IEEE
  147.     .long    0x7f800000
  148.